'use strict';

/**
 * 布控逻辑控制器
 */
const Code = require('../common/error_code');
const Cons = require('../common/constants');
const Util = require('../utils/hobot_util');
const userRecordModel = require('../models/record_user.model');
const UserCtrl = require('../controllers/user');
const ipcModel = require('../models/ipc.model');
const featureUrl = require('../../config/global_config').feature;
const httpUtil = require('../utils/http');

/**
 * 人员追踪
 */
async function search(ctx) {
    const params = ctx.request.body;
    // 校验参数
    if (!params.user_name && !params.user_avatar) {
        return ctx.error(Code.RET_TRACK_SEARCH_ERR_PARAM);
    }
    if (params.user_avatar && (!params.precision || !Util.isNumber2(Number(params.precision)))) {
        return ctx.error(Code.RET_TRACK_SEARCH_ERR_PARAM);
    }
    if (params.precision && (Number(params.precision) < 0 || Number(params.precision) > 100)) {
        return ctx.error(Code.RET_TRACK_SEARCH_ERR_PARAM);
    }
    if (!params.date_from || !params.date_to) {
        return ctx.error(Code.RET_TRACK_SEARCH_ERR_PARAM);
    }
    const f = "YYYYMMDDHHmmss";
    if (!Util.isDate(params.date_from, f) || !Util.isDate(params.date_to, f)) {
        return ctx.error(Code.RET_TRACK_SEARCH_ERR_TIME)
    }

    let cdt = {};
    if (params.date_from || params.date_to) {
        cdt.r_at = {
            $gte: new Date(Util.toISODate(params.date_from, 'YYYYMMDDHHmmss')),
            $lte: new Date(Util.toISODate(params.date_to, 'YYYYMMDDHHmmss'))
        };
    }

    let records = null;
    let rst = [];
    // 直接查询
    if (params.user_name) {
        cdt.u_nm = {$regex: params.user_name};
        rst = await queryUser(cdt);
    }
    // 通过头像检索
    else {
        const user_id = await UserCtrl.doRecog(params.user_avatar);
        // 注册用户的情况
        if (user_id) {
            cdt.u_id = user_id;
            rst = await queryUser(cdt);
        }
        // 陌生人的情况
        else {
            records = await searchStranger(Util.fmtDate(params.date_from, 'YYYY-MM-DD HH:mm:ss'),
                Util.fmtDate(params.date_to, 'YYYY-MM-DD HH:mm:ss'), params.user_avatar, params.precision);

            for (let i = 0; i < records.length; i++) {
                const item = records[i];
                const ipc = await ipcModel.findOne({_id: item.d_id});
                rst.push({
                    rec_id: item.id,
                    fms_score: Util.fmtSimilarity(item.score),
                    ipc_id: item.d_id,
                    ipc_name: ipc ? ipc.d_nm : '',
                    rec_time: item.r_at ? Util.fmtDate(item.r_at, 'YYYYMMDDHHmmss') : '',
                    rec_capture: [Util.getCaptureUrl(item.r_cp)]
                });
            }
        }
    }

    if (rst && rst.length > 0) {
        ctx.success(Code.RET_TRACK_SEARCH_OK, rst);
    }
    else {
        ctx.error(Code.RET_TRACK_SEARCH_ERR_NOT_EXIST);
    }
}

async function queryUser(condition) {
    let ret = [];
    const records = await userRecordModel.aggregate(
        [
            {$match: condition},
            {$limit: Cons.RECORD_MAX},
            {
                $lookup: {
                    from: 'ipc',
                    localField: 'd_id',
                    foreignField: '_id',
                    as: 'ipc_docs'
                }
            },
            {
                $project: {
                    _id: 1,
                    u_id: 1,
                    u_nm: 1,
                    r_at: 1,
                    r_cp: 1,
                    d_id: 1,
                    ipc: {$arrayElemAt: ['$ipc_docs', 0]}
                }
            },
            {$project: {_id: 1, u_id: 1, u_nm: 1, r_at: 1, r_cp: 1, d_id: 1, d_nm: '$ipc.d_nm'}},
            {$sort: {r_at: -1}}
        ]
    );

    for (let i = 0; i < records.length; i++) {
        const item = records[i];
        ret.push({
            rec_id: item._id,
            user_id: item.u_id,
            user_name: item.u_nm,
            ipc_id: item.d_id,
            ipc_name: item.d_nm,
            rec_time: item.r_at ? Util.fmtDate(item.r_at, 'YYYYMMDDHHmmss') : '',
            rec_capture: [Util.getCaptureUrl(item.r_cp)]
        });
    }

    return ret;
}

/**
 * 陌生人查找
 */
async function searchStranger(start, end, picture, precision) {
    const param = {
        start: start,
        end: end,
        pictures: [{type: 'jpg', picdata: picture}],
        precision: Number(precision) / 100
    };
    const rst = await httpUtil.post(featureUrl.record, param);
    if (rst.is_success === 0) {
        return rst.record;
    } else {
        return [];
    }
}

// 人员追踪
exports.search = search;
